// todo: 封装的cookie 拦截器,实现Cookie的持久化，比如 统一身份认证相关页面
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:path_provider/path_provider.dart';

class CookieInterceptor extends InterceptorsWrapper {
  late final CookieManager _cookieManager;
  late final PersistCookieJar _cookieJar;
  final Map<String, List<Cookie>> _urlCookies = {}; // 用于存储每个 URL 的 cookies

  static CookieInterceptor? _instance;
  // * 工厂方法返回 单个实例
  static Future<CookieInterceptor> getInstance() async {
    _instance ??= await create();
    return _instance!;
  }

  // * 工厂构造方法，异步创建 CookieInterceptor 实例，并持久化到本地存储
  static Future<CookieInterceptor> create() async {
    final appDocDir = await getApplicationDocumentsDirectory();
    final cookieJar =
        PersistCookieJar(storage: FileStorage('${appDocDir.path}/cookies'));

    final cookieManager = CookieManager(cookieJar);
    return CookieInterceptor._internal(cookieManager, cookieJar);
  }

  CookieInterceptor._internal(this._cookieManager, this._cookieJar);

  // * 插入到 Dio 拦截器链中的方法
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    // 调用 CookieManager 的请求处理，确保每个请求带上必要的 cookies
    _cookieManager.onRequest(options, handler);
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    final uri = response.requestOptions.uri;
    // 调用 CookieManager 的响应处理，更新和持久化新的 cookies
    _cookieManager.onResponse(response, handler);

    // 获取当前 URL 的 cookies 并存储在 _urlCookies Map 中
    _cookieJar.loadForRequest(uri).then((cookies) {
      _urlCookies[uri.toString()] = cookies;
    });
  }

  @override
  void onError(DioException err, ErrorInterceptorHandler handler) {
    // 处理错误，CookieManager 会检查是否有必要更新 cookies
    _cookieManager.onError(err, handler);
  }

  // 清除本地所有 cookies
  Future<void> clearCookies() async {
    await _cookieJar.deleteAll();
    _urlCookies.clear();
  }

  // 获取某个 URI 的 cookies
  Future<List<Cookie>> getCookies(String url) async {
    // return _cookieJar.loadForRequest(Uri.parse(url));
    return _urlCookies[url] ?? [];
  }

  // 获取所有 URL 的 cookies 映射
  Map<String, List<Cookie>> getAllCookies() {
    return _urlCookies;
  }
}
